package com.budwk.app.util;



import com.budwk.app.annotation.IGetter;

import java.io.Serializable;
import java.lang.invoke.SerializedLambda;
import java.lang.reflect.Method;

/**
 * 利用lambda方法引用获取字段属性
 *
 * @author : ywm
 * @describe :
 * @date : 2022/6/29 9:53
 */
public class ClassUtil {
    private static final String GET = "get";
    private static final String IS = "is";
    private static final String WRITE_REPLACE = "writeReplace";

    /**
     * 通过getter的方法引用获取字段名
     */
    public static <T> String getField(IGetter<T> fn) {
        SerializedLambda lambda;
        try {
            lambda = getSerializedLambda(fn);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        String methodName = lambda.getImplMethodName();
        String prefix = null;
        if (methodName.startsWith(GET)) {
            prefix = GET;
        } else if (methodName.startsWith(IS)) {
            prefix = IS;
        }
        if (prefix == null) {
            return null;
        }
        return toLowerCaseFirstOne(methodName.replace(prefix, ""));
    }

    /**
     * 关键在于这个方法
     */
    private static SerializedLambda getSerializedLambda(Serializable fn) throws Exception {
        Method method = fn.getClass().getDeclaredMethod(WRITE_REPLACE);
        method.setAccessible(Boolean.TRUE);
        SerializedLambda lambda = (SerializedLambda) method.invoke(fn);
        return lambda;
    }

    /**
     * 字符串首字母转小写
     */
    private static String toLowerCaseFirstOne(String field) {
        if (Character.isLowerCase(field.charAt(0)))
            return field;
        else {
            char firstOne = Character.toLowerCase(field.charAt(0));
            String other = field.substring(1);
            return new StringBuilder().append(firstOne).append(other).toString();
        }
    }
}